package com.ecr.hub.service.impression.pdf.impl;

import java.awt.Color;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.stereotype.Component;

import com.ecr.hub.ApplicationException;
import com.ecr.hub.model.composition.Composition;
import com.ecr.hub.model.enumeration.HubBundleType;
import com.ecr.hub.model.enumeration.HubLading;
import com.ecr.hub.model.enumeration.HubSillonType;
import com.ecr.hub.model.rail.Rail;
import com.ecr.hub.model.sillon.Sillon;
import com.ecr.hub.model.wagon.Wagon;
import com.ecr.hub.service.impression.pdf.IHubPdfCreator;
import com.ecr.hub.util.LabelUtils;
import com.ecr.hub.util.WagonUtils;
import com.lowagie.text.Chunk;
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.Image;
import com.lowagie.text.Paragraph;
import com.lowagie.text.Phrase;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfWriter;

/**
 * Cette classe contient énormément de fonctions recopiées dont le contenu
 * diffère très peu car de nombreuses impressions se ressemblent. Pour l'instant
 * on ne cherche pas à optimiser le code (beaucoup de copier coller), cela
 * permet dans un premier temsp d'être plus flexible par rapport à la demande
 * utilisateur. A voir dans un second temps pour factoriser le code et diviser
 * le nombre de ligne par deux ou trois. (Comme cette partie n'est pas critique
 * en termes d'algo...).
 * 
 */
@Component("hubPdfCreator")
public class HubPdfCreatorImpl extends AbstractPdfCreator implements
		IHubPdfCreator {

	// Le nombre de lignes à afficher par page pour les sillons.
	private static final int NB_SILLONS_BY_PAGE = 30;
	// Le nombre de lignes à afficher par page pour les wagons sur une voie.
	private static final int NB_WAGONS_RAIL_BY_PAGE = 25;
	// Le nombre de lignes à afficher par page pour le programme de travail.
	private static final int NB_WAGONS_WORKING_PLAN_BY_PAGE = 25;
	// Le nombre de lignes à afficher par page pour le programme de travail.
	private static final int NB_WAGONS_FORMATION_PLAN_BY_PAGE = 25;
	// Le nombre de lignes à afficher par page pour le relevé de composition.
	private static final int NB_WAGONS_COMPOSITION_PLAN_BY_PAGE = 25;

	private static final float[] HEADER_DIMENSION = { 3.0f, 4.0f, 2f, 1.5f };

	private static final float[] TABLE_RAIL_DIMENSION = { 0.6f, 0.8f, 1.3f,
			0.7f, 0.7f, 0.5f, 0.7f, 0.7f, 0.7f, 1.5f, 4.0f };

	private static final float[] TABLE_WORKING_PLAN_DIMENSION = { 0.7f, 1.5f,
			0.8f, 1.8f, 0.8f, 0.8f, 0.8f, 0.8f, 0.8f, 4.0f };

	private static final float[] TABLE_SILLON_DIMENSION = { 0.4f, 0.4f, 0.4f,
			1.0f, 1.02f, 1.0f, 0.5f, 0.5f, 0.5f, 2.0f };

	private static final float[] TABLE_FORMATION_PLAN_DIMENSION = { 1.8f, 0.7f,
			1.5f, 0.8f, 0.8f, 0.8f, 0.8f, 0.8f, 0.8f, 4.0f };

	private static final float[] TABLE_COMPOSITION_PLAN_DIMENSION = { 0.7f,
			1.5f, 0.8f, 0.8f, 0.8f, 0.8f, 0.8f, 0.8f, 1.5f, 2.5f };

	/**
	 * En-tête pour l'ensemble des documents pdf. Il s'agit d'un en-tête
	 * générique avec un titre, un sous titre (qui est en fait le titre du
	 * document), un logo, une date et une heure de création. Si d'autres
	 * données doivent êtres rajoutées, alors un second panneau est additionné.
	 * 
	 */
	private float addLandscapeHeaderTable(Document document, String title,
			String subTitle, String header_img_path, int page, int nbPages)
			throws ApplicationException, DocumentException {

		PdfPTable header = new PdfPTable(HEADER_DIMENSION);
		Image img = getImage(header_img_path);
		header.setWidthPercentage(100);

		PdfPCell cellLogo = new PdfPCell();
		PdfPCell cellTitle = new PdfPCell();
		PdfPCell cellDate = new PdfPCell();
		PdfPCell cellPage = new PdfPCell();
		cellLogo.setBorder(Rectangle.NO_BORDER);
		cellTitle.setBorder(Rectangle.NO_BORDER);
		cellDate.setBorder(Rectangle.NO_BORDER);
		cellPage.setBorder(Rectangle.NO_BORDER);

		Chunk c = new Chunk(img, 0, 0, true);
		Phrase p = new Phrase(c);
		cellLogo.addElement(p);
		header.addCell(cellLogo);

		cellTitle.addElement(new Phrase(title, FONT_TITRE_14));
		cellTitle.addElement(new Phrase(subTitle, FONT_TITRE_12));
		cellTitle.setVerticalAlignment(Element.ALIGN_TOP);
		header.addCell(cellTitle);

		String strDate = LabelUtils.getLabel("print.doc.common.date") + " : "
				+ datePdf;
		cellDate.addElement(new Phrase(strDate, FONT_TITRE_10));
		String strTime = LabelUtils.getLabel("print.doc.common.time") + " : "
				+ timePdf;
		cellDate.addElement(new Phrase(strTime, FONT_TITRE_10));
		header.addCell(cellDate);

		String strPage = LabelUtils.getLabel("print.doc.common.page")
				+ " : %d/%d";
		cellPage.addElement(new Phrase(String.format(strPage, page, nbPages),
				FONT_TITRE_10));
		header.addCell(cellPage);
		document.add(header);
		return header.getTotalHeight();
	}

	/*
	 * ********************************************************
	 * Document pdf pour la photo du centre de tri . (On se rebranche sur la
	 * photo de la voie....)
	 * ********************************************************
	 */
	@Override
	public void pdfDocumentHub(PdfWriter pdfWriter, Document document,
			String realPathImgLogo, List<Rail> lstRails)
			throws ApplicationException, DocumentException {

		this.headerImgPath = realPathImgLogo;
		int nbPages = lstRails.size();
		int line = 1;
		// Il faut aussi prendre en compte la pagination interne de chaque rail.
		for (Rail rail : lstRails) {
			if ((rail.getLstWagons().size() / NB_WAGONS_RAIL_BY_PAGE) > 1)
				nbPages += (rail.getLstWagons().size() / NB_WAGONS_RAIL_BY_PAGE) - 1;
		}
		document.open();

		String title = LabelUtils.getLabel("print.doc.hub.title");
		PdfPTable tablePage = null;

		for (Rail rail : lstRails) {
			line = 1;
			tablePage = newRailTablePage(document, 1, nbPages, rail, title);
			for (Wagon wagon : rail.getLstWagons()) {
				if (line == NB_WAGONS_RAIL_BY_PAGE) {
					document.add(tablePage);
					document.newPage();
					tablePage = newRailTablePage(document,
							pdfWriter.getPageNumber(), nbPages, rail, title);
					line = 1;
				}
				addWagonRail(tablePage, wagon);
				line++;
			}
			addRailFooter(tablePage);
			document.add(tablePage);
			document.newPage();
		}
		addMetaData(document, title, "");
		setDefaultZoom(pdfWriter, 11000);
		document.close();
	}

	// *****************************************************
	// Document pdf pour la photo de la voie.
	// *****************************************************

	@Override
	public void pdfDocumentRail(PdfWriter pdfWriter, Document document,
			String realPathImgLogo, List<Wagon> lstWagons, Rail rail)
			throws ApplicationException, DocumentException {

		int line = 1;
		int nbPages = getNbpages(lstWagons, NB_WAGONS_RAIL_BY_PAGE, false);
		this.headerImgPath = realPathImgLogo;
		document.open();

		String title = LabelUtils.getLabel("print.doc.rail.title");

		// Première page
		PdfPTable tablePage = newRailTablePage(document, 1, nbPages, rail,
				title);

		// Itération sur la liste des wagons.
		for (Wagon wagon : lstWagons) {
			if (line == NB_WAGONS_RAIL_BY_PAGE) {
				document.add(tablePage);
				document.newPage();
				tablePage = newRailTablePage(document,
						pdfWriter.getPageNumber(), nbPages, rail, title);
				line = 1;
			}
			addWagonRail(tablePage, wagon);
			line++;
		}
		addRailFooter(tablePage);
		document.add(tablePage);
		addMetaData(document, title, "");
		setDefaultZoom(pdfWriter, 11000);
		document.close();
	}

	private PdfPTable newRailTablePage(Document document, int page,
			int nbPages, Rail rail, String title) throws ApplicationException,
			DocumentException {

		String subTitle = LabelUtils.getLabel("print.doc.rail.subtitle")
				+ " : " + rail.getNumber() + "  ";

		if (rail.getTypeBundle().getId() == HubBundleType.SORT.getValue()) {
			subTitle += rail.getDestinationLabel();
		} else {
			subTitle += rail.getTypeBundle().getLabel();
		}

		// Ajout de l'entête
		addLandscapeHeaderTable(document, title, subTitle, headerImgPath, page,
				nbPages);
		// Aeration
		document.add(new Paragraph(" "));
		document.add(new Paragraph(" "));
		// Nb de colonne + taille de chaque colonne
		PdfPTable table = new PdfPTable(TABLE_RAIL_DIMENSION);
		table.setWidthPercentage(100);
		table.getDefaultCell().setUseAscender(true);
		table.getDefaultCell().setUseDescender(true);
		table.getDefaultCell().setBackgroundColor(Color.LIGHT_GRAY);

		PdfPCell cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.position"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.rail.type.position"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.wagon"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.wagon.lading"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.wagon.length"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.wagon.weight"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.wagon.weight.loading"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.wagon.weight.total"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.wagon.brake.force"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.wagon.destination"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.comment"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		table.getDefaultCell().setBackgroundColor(null);
		table.getDefaultCell().setVerticalAlignment(Element.ALIGN_BOTTOM);
		return table;
	}

	private void addWagonRail(PdfPTable table, Wagon wagon)
			throws DocumentException {

		String typePos = (wagon.getCurrentPos().isPosReal()) ? LabelUtils
				.getLabel("print.doc.common.real") : LabelUtils
				.getLabel("print.doc.common.theo");

		String length = (wagon.getType().getTotalLength() != 0) ? simpleDecimalFormat
				.format(wagon.getType().getTotalLength()) : LabelUtils
				.getLabel("common.nc");

		String curb_weight = (wagon.getType().getCurbWeight() != 0) ? simpleDecimalFormat
				.format(wagon.getType().getCurbWeight()) : LabelUtils
				.getLabel("common.nc");

		String lading_weight = ZERO;

		if (HubLading.LOADED.getValue().equals(wagon.getLading())) {
			lading_weight = (wagon.getWeightLading() > 0) ? simpleDecimalFormat
					.format(wagon.getWeightLading()) : "* " + ZERO;
		}

		String total_weight = simpleDecimalFormat.format(wagon.getType()
				.getCurbWeight() + wagon.getWeightLading());

		if ((wagon.getType().getCurbWeight() == 0 || wagon.getWeightLading() == 0)
				&& HubLading.LOADED.getValue().equals(wagon.getLading())) {
			total_weight = "* " + total_weight;
		}

		String brake_force = (wagon.getBrakeForce() > 0) ? Integer
				.toString((int) wagon.getBrakeForce()) : "* ";

		String destination = (wagon.getDestinationId() > 1) ? wagon
				.getDestinationLabel() : LabelUtils.getLabel("common.nc");

		PdfPCell cell = new PdfPCell(new Phrase(Integer.toString(wagon
				.getCurrentPos().getPosNum() + 1), FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		table.addCell(cell);

		table.addCell(new Phrase(typePos, FONT_TABLE_CELL));

		cell = new PdfPCell(new Phrase(
				WagonUtils.formatExtId(wagon.getExtId()), FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		table.addCell(cell);

		table.addCell(new Phrase(wagon.getLading(), FONT_TABLE_CELL));

		cell = new PdfPCell(new Phrase(length, FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(curb_weight, FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(lading_weight, FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(total_weight, FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(brake_force, FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		table.addCell(new Phrase(" " + destination, FONT_TABLE_CELL));

		table.addCell(new Phrase(wagon.getComment(), FONT_TABLE_CELL));
	}

	public void addRailFooter(PdfPTable table) {

		PdfPCell cell = new PdfPCell(new Phrase("* "
				+ LabelUtils.getLabel("print.doc.common.legend"),
				FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_LEFT);
		cell.setBorder(Rectangle.NO_BORDER);
		cell.setColspan(11);
		table.addCell(cell);
	}

	// *****************************************************
	// Document pdf pour le programme de travail.
	// *****************************************************

	@Override
	public void pdfDocumentWorkingPlan(PdfWriter pdfWriter, Document document,
			String realPathImgLogo, Sillon sillon,
			List<Composition> lstCompositions) throws ApplicationException,
			DocumentException {

		int line = 1;
		int prevNumLot = 0;
		int nbPages = getNbpages(lstCompositions,
				NB_WAGONS_WORKING_PLAN_BY_PAGE, true);
		this.headerImgPath = realPathImgLogo;
		document.open();

		String title = LabelUtils.getLabel("print.doc.wplan.title");

		// Première page
		PdfPTable tablePage = newWorkingPlanTablePage(document, 1, nbPages,
				sillon, title);
		// Itération sur la liste des wagons.
		for (Composition composition : lstCompositions) {
			if (line == NB_WAGONS_WORKING_PLAN_BY_PAGE) {
				document.add(tablePage);
				document.newPage();
				tablePage = newWorkingPlanTablePage(document,
						pdfWriter.getPageNumber(), nbPages, sillon, title);
				line = 1;
			}
			// Rupture de séquence.
			if (composition.getWagon().getNumLot() != prevNumLot) {
				addSeparator(tablePage, composition.getWagon().getNumLot());
				prevNumLot = composition.getWagon().getNumLot();
				line++; // Prend une ligne pour afficher le lot.
			}
			addCompositionWorkingPlan(tablePage, composition);
			line++;
		}
		// Ajout des totaux.
		addWorkingPlanFooter(tablePage, sillon, lstCompositions);

		document.add(tablePage);
		addMetaData(document, title, "");
		setDefaultZoom(pdfWriter, 11000);
		document.close();
	}

	private PdfPTable newWorkingPlanTablePage(Document document, int page,
			int nbPages, Sillon sillon, String title)
			throws ApplicationException, DocumentException {

		String subTitle = LabelUtils.getLabel("print.doc.wplan.subtitle")
				+ " : " + sillon.getExtId();

		// Ajout de l'entête
		addLandscapeHeaderTable(document, title, subTitle, headerImgPath, page,
				nbPages);
		// Ajout du second en tête spécifique.
		addLandscapeWorkingplanHeader(document, sillon);
		// Aeration
		document.add(new Paragraph(" "));
		document.add(new Paragraph(" "));
		// Nb de colonne + taille de chaque colonne
		PdfPTable table = new PdfPTable(TABLE_WORKING_PLAN_DIMENSION);
		table.setWidthPercentage(100);
		table.getDefaultCell().setUseAscender(true);
		table.getDefaultCell().setUseDescender(true);
		table.getDefaultCell().setBackgroundColor(Color.LIGHT_GRAY);

		PdfPCell cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.position"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.wagon"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.wagon.lading"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.wplan.rail.destination"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.wagon.length"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.wagon.weight"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.wagon.weight.loading"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.wagon.weight.total"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.wagon.brake.force"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.comment"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		table.getDefaultCell().setBackgroundColor(null);
		table.getDefaultCell().setVerticalAlignment(Element.ALIGN_BOTTOM);
		return table;
	}

	private void addLandscapeWorkingplanHeader(Document document, Sillon sillon)
			throws DocumentException {

		PdfPTable headerWorkingplan = new PdfPTable(HEADER_DIMENSION);
		headerWorkingplan.setWidthPercentage(100);

		// Même dénomination pour les cellules afin de mieux se repérer.
		PdfPCell cellLogo = new PdfPCell();
		PdfPCell cellTitle = new PdfPCell();
		PdfPCell cellDate = new PdfPCell();
		PdfPCell cellPage = new PdfPCell();
		cellLogo.setBorder(Rectangle.NO_BORDER);
		cellTitle.setBorder(Rectangle.NO_BORDER);
		cellDate.setBorder(Rectangle.NO_BORDER);
		cellPage.setBorder(Rectangle.NO_BORDER);

		String strRail = LabelUtils.getLabel("print.doc.wplan.rail") + " : ";
		strRail += (sillon.getRailExtId() != null && sillon.getRailExtId()
				.length() > 0) ? sillon.getRailExtId() + " ("
				+ sillon.getRailLabel() + ")" : LabelUtils
				.getLabel("common.nc");

		cellLogo.addElement(new Phrase(strRail, FONT_TITRE_10));
		headerWorkingplan.addCell(cellLogo);

		String strOrigin = LabelUtils.getLabel("print.doc.wplan.origin")
				+ " : " + sillon.getOrigin();
		cellTitle.addElement(new Phrase(strOrigin, FONT_TITRE_10));
		headerWorkingplan.addCell(cellTitle);

		String strTime = LabelUtils.getLabel("print.doc.wplan.arrival.time")
				+ " : ";
		strTime += (sillon.getRealMovementTime() != null && sillon
				.getRealMovementTime().length() == 5) ? sillon
				.getRealMovementTime() : LabelUtils.getLabel("common.nc");

		cellDate.addElement(new Phrase(strTime, FONT_TITRE_10));
		headerWorkingplan.addCell(cellDate);

		cellPage.addElement(new Phrase("", FONT_TITRE_10));
		headerWorkingplan.addCell(cellPage);
		document.add(headerWorkingplan);
	}

	private void addCompositionWorkingPlan(PdfPTable table,
			Composition composition) throws DocumentException {

		PdfPCell cell;

		String length = (composition.getWagon().getType().getTotalLength() != 0) ? simpleDecimalFormat
				.format(composition.getWagon().getType().getTotalLength())
				: LabelUtils.getLabel("common.nc");

		String curb_weight = (composition.getWagon().getType().getCurbWeight() != 0) ? simpleDecimalFormat
				.format(composition.getWagon().getType().getCurbWeight())
				: LabelUtils.getLabel("common.nc");

		String lading_weight = ZERO;

		if (HubLading.LOADED.getValue().equals(
				composition.getWagon().getLading())) {
			lading_weight = (composition.getWagon().getWeightLading() > 0) ? simpleDecimalFormat
					.format(composition.getWagon().getWeightLading()) : "* "
					+ ZERO;
		}

		String total_weight = simpleDecimalFormat.format(composition.getWagon()
				.getType().getCurbWeight()
				+ composition.getWagon().getWeightLading());

		if ((composition.getWagon().getType().getCurbWeight() == 0 || composition
				.getWagon().getWeightLading() == 0)
				&& HubLading.LOADED.getValue().equals(
						composition.getWagon().getLading())) {
			total_weight = "* " + total_weight;
		}

		String brake_force = (composition.getWagon().getBrakeForce() > 0) ? Integer
				.toString((int) composition.getWagon().getBrakeForce()) : "* ";

		String rail = "  " + composition.getRailNumber() + "  "
				+ composition.getDestinationLabel();

		cell = new PdfPCell(new Phrase(Integer.toString(composition.getWagon()
				.getCurrentPos().getPosNum() + 1), FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(WagonUtils.formatExtId(composition
				.getWagon().getExtId()), FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		table.addCell(cell);

		table.addCell(new Phrase(composition.getWagon().getLading(),
				FONT_TABLE_CELL));

		cell = new PdfPCell(new Phrase(rail, FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_LEFT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(length, FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(curb_weight, FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(lading_weight, FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(total_weight, FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(brake_force, FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		table.addCell(new Phrase(composition.getComment(), FONT_TABLE_CELL));
	}

	public void addWorkingPlanFooter(PdfPTable table, Sillon sillon,
			List<Composition> lstCompositions) throws DocumentException {

		List<String> lstTotal = calcTotal(sillon, lstCompositions);

		PdfPCell cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.total") + " : ",
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		cell.setColspan(4);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(lstTotal.get(0), FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(lstTotal.get(1), FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(lstTotal.get(2), FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(lstTotal.get(3), FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(lstTotal.get(4), FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase());
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase("* "
				+ LabelUtils.getLabel("print.doc.common.legend"),
				FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_LEFT);
		cell.setBorder(Rectangle.NO_BORDER);
		cell.setColspan(10);
		table.addCell(cell);
	}

	private void addSeparator(PdfPTable table, int numLot) {

		PdfPCell cell = new PdfPCell();
		String strNumLot = LabelUtils.getLabel("print.doc.common.wagon.lot")
				+ ":  " + numLot;
		cell.addElement(new Phrase(strNumLot, FONT_TABLE_CELL_BOLD));
		cell.setColspan(11);
		table.addCell(cell);
	}

	/*
	 * ********************************************************
	 * Document pdf pour le planning des sillons.
	 * ********************************************************
	 */
	@Override
	public void pdfDocumentPlanning(PdfWriter pdfWriter, Document document,
			String realPathImgLogo, List<Sillon> lstSillons, Date date,
			Date dateEnd) throws ApplicationException, DocumentException {

		int line = 1;
		int nbPages = getNbpages(lstSillons, NB_SILLONS_BY_PAGE, false);
		this.headerImgPath = realPathImgLogo;
		document.open();

		String title = LabelUtils.getLabel("print.doc.planning.title");

		String subTitle = LabelUtils.getLabel("print.doc.planning.subtitle")
				+ " : " + simpleDateFormat.format(date);

		// Si les deux dates sont différentes on complète le sous-titre.
		if (date.compareTo(dateEnd) < 0) {
			subTitle += " " + LabelUtils.getLabel("print.doc.common.au")
					+ " : " + simpleDateFormat.format(dateEnd);
		}

		// Première page
		PdfPTable tablePage = newSillonTablePage(document, 1, nbPages, title,
				subTitle);

		// Itération sur la liste des sillons.
		for (Sillon sillon : lstSillons) {
			if (line == NB_SILLONS_BY_PAGE) {
				document.add(tablePage);
				document.newPage();
				tablePage = newSillonTablePage(document,
						pdfWriter.getPageNumber(), nbPages, title, subTitle);
				line = 1;
			}
			addSillon(tablePage, sillon);
			line++;
		}
		addPlanningFooter(tablePage);
		document.add(tablePage);
		addMetaData(document, title, "");
		setDefaultZoom(pdfWriter, 11000);
		document.close();
	}

	private PdfPTable newSillonTablePage(Document document, int page,
			int nbPages, String title, String subTitle)
			throws ApplicationException, DocumentException {

		// Ajout de l'entête
		addLandscapeHeaderTable(document, title, subTitle, headerImgPath, page,
				nbPages);
		// Aeration
		document.add(new Paragraph(" "));
		document.add(new Paragraph(" "));
		// Nb de colonne + taille de chaque colonne
		PdfPTable table = new PdfPTable(TABLE_SILLON_DIMENSION);
		table.setWidthPercentage(100);
		table.getDefaultCell().setUseAscender(true);
		table.getDefaultCell().setUseDescender(true);
		table.getDefaultCell().setBackgroundColor(Color.LIGHT_GRAY);

		PdfPCell cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.planning.sillon"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.planning.type"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.planning.loaded"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.tcms.trainid"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.planning.origin"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.planning.destination"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.planning.date"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.planning.departure.time"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.planning.arrival.time"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.comment"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		table.getDefaultCell().setBackgroundColor(null);
		table.getDefaultCell().setVerticalAlignment(Element.ALIGN_BOTTOM);
		return table;
	}

	private void addSillon(PdfPTable table, Sillon sillon)
			throws DocumentException {

		String strTypeSillon = (HubSillonType.ARRIVAL.getValue().equals(sillon
				.getType())) ? LabelUtils
				.getLabel("print.doc.planning.arrival") : LabelUtils
				.getLabel("print.doc.planning.departure");

		String strDepartureTime = (HubSillonType.ARRIVAL.getValue()
				.equals(sillon.getType())) ? LabelUtils
				.getLabel("print.doc.planning.time.default") : sillon
				.getMovementTime();

		String strArrivalTime = (HubSillonType.ARRIVAL.getValue().equals(sillon
				.getType())) ? sillon.getMovementTime() : LabelUtils
				.getLabel("print.doc.planning.time.default");

		String strDepartureDate = simpleDateFormat.format(sillon
				.getMovementDate());

		String strLading = (sillon.getLading() != null && sillon.getLading()
				.trim().length() > 0) ? sillon.getLading() : LabelUtils
				.getLabel("common.nc");

		String strSillonExtId = sillon.getExtId();
		if (sillon.isUpdated())
			strSillonExtId += " *";

		PdfPCell cell = new PdfPCell(
				new Phrase(strSillonExtId, FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_LEFT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(strTypeSillon, FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(strLading, FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		table.addCell(cell);

		cell = new PdfPCell(
				new Phrase(sillon.getTcmsTrainId(), FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_LEFT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(sillon.getOrigin(), FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_LEFT);
		table.addCell(cell);

		cell = new PdfPCell(
				new Phrase(sillon.getDestination(), FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_LEFT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(strDepartureDate, FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(strDepartureTime, FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(strArrivalTime, FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(sillon.getComment(), FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_LEFT);
		table.addCell(cell);
	}

	public void addPlanningFooter(PdfPTable table) {

		PdfPCell cell = new PdfPCell(new Phrase("* "
				+ LabelUtils.getLabel("print.doc.planning.legend"),
				FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_LEFT);
		cell.setBorder(Rectangle.NO_BORDER);
		cell.setColspan(10);
		table.addCell(cell);
	}

	/*
	 * ********************************************************
	 * Document pdf pour le programme de formation.
	 * ********************************************************
	 */
	@Override
	public void pdfDocumentFormationPlan(PdfWriter pdfWriter,
			Document document, String realPathImgLogo, Sillon sillon,
			List<Composition> lstCompositions) throws ApplicationException,
			DocumentException {

		int line = 1;
		int prevNumLot = 0;
		int nbPages = getNbpages(lstCompositions,
				NB_WAGONS_FORMATION_PLAN_BY_PAGE, true);
		this.headerImgPath = realPathImgLogo;

		document.open();

		String title = LabelUtils.getLabel("print.doc.form.title");

		// Première page
		PdfPTable tablePage = newFormationPlanTablePage(document, 1, nbPages,
				sillon, title);
		// Itération sur la liste des wagons.
		for (Composition composition : lstCompositions) {
			if (line == NB_WAGONS_FORMATION_PLAN_BY_PAGE) {
				document.add(tablePage);
				document.newPage();
				tablePage = newFormationPlanTablePage(document,
						pdfWriter.getPageNumber(), nbPages, sillon, title);
				line = 1;
			}
			// Rupture de séquence.
			if (composition.getWagon().getNumLot() != prevNumLot) {
				addSeparator(tablePage, composition.getWagon().getNumLot());
				prevNumLot = composition.getWagon().getNumLot();
				line++; // Prend une ligne pour afficher le lot.
			}
			addCompositionFormationPlan(tablePage, composition);
			line++;
		}

		addFormationPlanFooter(tablePage, sillon, lstCompositions);

		document.add(tablePage);
		addMetaData(document, title, "");
		setDefaultZoom(pdfWriter, 11000);
		document.close();
	}

	private PdfPTable newFormationPlanTablePage(Document document, int page,
			int nbPages, Sillon sillon, String title)
			throws ApplicationException, DocumentException {

		String subTitle = LabelUtils.getLabel("print.doc.wplan.subtitle")
				+ " : " + sillon.getExtId();

		// Ajout de l'entête
		addLandscapeHeaderTable(document, title, subTitle, headerImgPath, page,
				nbPages);
		// Ajout du second en tête spécifique.
		addLandscapeFormationPlanHeader(document, sillon);
		// Aeration
		document.add(new Paragraph(" "));
		document.add(new Paragraph(" "));
		// Nb de colonne + taille de chaque colonne
		PdfPTable table = new PdfPTable(TABLE_FORMATION_PLAN_DIMENSION);
		table.setWidthPercentage(100);
		table.getDefaultCell().setUseAscender(true);
		table.getDefaultCell().setUseDescender(true);
		table.getDefaultCell().setBackgroundColor(Color.LIGHT_GRAY);

		PdfPCell cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.wplan.rail.destination"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.position"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.wagon"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.wagon.lading"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.wagon.length"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.wagon.weight"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.wagon.weight.loading"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.wagon.weight.total"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.wagon.brake.force"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.comment"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		table.getDefaultCell().setBackgroundColor(null);
		table.getDefaultCell().setVerticalAlignment(Element.ALIGN_BOTTOM);
		return table;
	}

	private void addLandscapeFormationPlanHeader(Document document,
			Sillon sillon) throws DocumentException {

		PdfPTable headerWorkingplan = new PdfPTable(HEADER_DIMENSION);
		headerWorkingplan.setWidthPercentage(100);

		// Même dénomination pour les cellules afin de mieux se repérer.
		PdfPCell cellLogo = new PdfPCell();
		PdfPCell cellTitle = new PdfPCell();
		PdfPCell cellDate = new PdfPCell();
		PdfPCell cellPage = new PdfPCell();
		cellLogo.setBorder(Rectangle.NO_BORDER);
		cellTitle.setBorder(Rectangle.NO_BORDER);
		cellDate.setBorder(Rectangle.NO_BORDER);
		cellPage.setBorder(Rectangle.NO_BORDER);

		String strRailFormation = LabelUtils.getLabel("print.doc.form.rail")
				+ " : ";
		strRailFormation += (sillon.getRailFormationExtId() != null && sillon
				.getRailFormationExtId().length() > 0) ? sillon
				.getRailFormationExtId()
				+ " ("
				+ sillon.getRailFormationLabel() + ")" : LabelUtils
				.getLabel("common.nc");

		String strRailDeparture = LabelUtils
				.getLabel("print.doc.form.rail.departure") + " : ";
		strRailDeparture += (sillon.getRailExtId() != null && sillon
				.getRailLabel().length() > 0) ? sillon.getRailExtId() + " ("
				+ sillon.getRailLabel() + ")" : LabelUtils
				.getLabel("common.nc");

		cellLogo.addElement(new Phrase(strRailFormation, FONT_TITRE_10));
		cellLogo.addElement(new Phrase(strRailDeparture, FONT_TITRE_10));
		headerWorkingplan.addCell(cellLogo);

		String strOrigin = LabelUtils.getLabel("print.doc.form.destination")
				+ " : " + sillon.getDestination();
		cellTitle.addElement(new Phrase(strOrigin, FONT_TITRE_10));
		headerWorkingplan.addCell(cellTitle);

		String strTime = LabelUtils.getLabel("print.doc.form.departure.time")
				+ " : ";
		strTime += (sillon.getMovementTime() != null && sillon
				.getMovementTime().length() == 5) ? sillon.getMovementTime()
				: LabelUtils.getLabel("common.nc");

		cellDate.addElement(new Phrase(strTime, FONT_TITRE_10));
		headerWorkingplan.addCell(cellDate);

		cellPage.addElement(new Phrase("", FONT_TITRE_10));
		headerWorkingplan.addCell(cellPage);
		document.add(headerWorkingplan);
	}

	private void addCompositionFormationPlan(PdfPTable table,
			Composition composition) throws DocumentException {

		PdfPCell cell;

		String length = (composition.getWagon().getType().getTotalLength() != 0) ? simpleDecimalFormat
				.format(composition.getWagon().getType().getTotalLength())
				: LabelUtils.getLabel("common.nc");

		String curb_weight = (composition.getWagon().getType().getCurbWeight() != 0) ? simpleDecimalFormat
				.format(composition.getWagon().getType().getCurbWeight())
				: LabelUtils.getLabel("common.nc");

		String lading_weight = ZERO;

		if (HubLading.LOADED.getValue().equals(
				composition.getWagon().getLading())) {
			lading_weight = (composition.getWagon().getWeightLading() > 0) ? simpleDecimalFormat
					.format(composition.getWagon().getWeightLading()) : "* "
					+ ZERO;
		}

		String total_weight = simpleDecimalFormat.format(composition.getWagon()
				.getType().getCurbWeight()
				+ composition.getWagon().getWeightLading());

		if ((composition.getWagon().getType().getCurbWeight() == 0 || composition
				.getWagon().getWeightLading() == 0)
				&& HubLading.LOADED.getValue().equals(
						composition.getWagon().getLading())) {
			total_weight = "* " + total_weight;
		}

		String brake_force = (composition.getWagon().getBrakeForce() > 0) ? Integer
				.toString((int) composition.getWagon().getBrakeForce()) : "* ";

		String rail = "  " + composition.getRailNumber() + "  "
				+ composition.getDestinationLabel();

		cell = new PdfPCell(new Phrase(rail, FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_LEFT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(Integer.toString(composition.getWagon()
				.getCurrentPos().getPosNum() + 1), FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(WagonUtils.formatExtId(composition
				.getWagon().getExtId()), FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		table.addCell(cell);

		table.addCell(new Phrase(composition.getWagon().getLading(),
				FONT_TABLE_CELL));

		cell = new PdfPCell(new Phrase(length, FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(curb_weight, FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(lading_weight, FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(total_weight, FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(brake_force, FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		table.addCell(new Phrase(composition.getComment(), FONT_TABLE_CELL));
	}

	public void addFormationPlanFooter(PdfPTable table, Sillon sillon,
			List<Composition> lstCompositions) throws DocumentException {

		List<String> lstTotal = calcTotal(sillon, lstCompositions);

		PdfPCell cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.total") + " : ",
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		cell.setColspan(4);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(lstTotal.get(0), FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(lstTotal.get(1), FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(lstTotal.get(2), FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(lstTotal.get(3), FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(lstTotal.get(4), FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase());
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase("* "
				+ LabelUtils.getLabel("print.doc.common.legend"),
				FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_LEFT);
		cell.setBorder(Rectangle.NO_BORDER);
		cell.setColspan(10);
		table.addCell(cell);
	}

	/*
	 * ********************************************************
	 * Document pdf pour le relevé de composition.
	 * ********************************************************
	 */
	@Override
	public void pdfDocumentCompositionPlan(PdfWriter pdfWriter,
			Document document, String realPathImgLogo, Sillon sillon,
			List<Composition> lstCompositions) throws ApplicationException,
			DocumentException {

		int line = 1;
		int nbPages = getNbpages(lstCompositions,
				NB_WAGONS_COMPOSITION_PLAN_BY_PAGE, false);
		this.headerImgPath = realPathImgLogo;
		document.open();

		String title = LabelUtils.getLabel("print.doc.compo.title");

		// Première page
		PdfPTable tablePage = newCompositionPlanTablePage(document, 1, nbPages,
				sillon, title);
		// Itération sur la liste des wagons.
		for (Composition composition : lstCompositions) {
			if (line == NB_WAGONS_COMPOSITION_PLAN_BY_PAGE) {
				document.add(tablePage);
				document.newPage();
				tablePage = newCompositionPlanTablePage(document,
						pdfWriter.getPageNumber(), nbPages, sillon, title);
				line = 1;
			}
			// Ajout de la ligne dans le document.
			addCompositionCompositionPlan(tablePage, composition, sillon);
			line++;
		}
		addCompositionPlanFooter(tablePage, sillon, lstCompositions);

		document.add(tablePage);
		addMetaData(document, title, "");
		setDefaultZoom(pdfWriter, 11000);
		document.close();
	}

	private PdfPTable newCompositionPlanTablePage(Document document, int page,
			int nbPages, Sillon sillon, String title)
			throws ApplicationException, DocumentException {

		String subTitle = LabelUtils.getLabel("print.doc.wplan.subtitle")
				+ " : " + sillon.getExtId();

		// Ajout de l'entête
		addLandscapeHeaderTable(document, title, subTitle, headerImgPath, page,
				nbPages);
		// Ajout du second en tête spécifique.
		addLandscapeCompositionPlanHeader(document, sillon);
		// Aeration
		document.add(new Paragraph(" "));
		document.add(new Paragraph(" "));
		// Nb de colonne + taille de chaque colonne
		PdfPTable table = new PdfPTable(TABLE_COMPOSITION_PLAN_DIMENSION);
		table.setWidthPercentage(100);
		table.getDefaultCell().setUseAscender(true);
		table.getDefaultCell().setUseDescender(true);
		table.getDefaultCell().setBackgroundColor(Color.LIGHT_GRAY);

		PdfPCell cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.position"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.wagon"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.wagon.lading"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.wagon.length"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.wagon.weight"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.wagon.weight.loading"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.wagon.weight.total"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.wagon.brake.force"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.destination"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.comment"),
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		table.addCell(cell);

		table.getDefaultCell().setBackgroundColor(null);
		table.getDefaultCell().setVerticalAlignment(Element.ALIGN_BOTTOM);
		return table;
	}

	private void addLandscapeCompositionPlanHeader(Document document,
			Sillon sillon) throws DocumentException {

		PdfPTable headerWorkingplan = new PdfPTable(HEADER_DIMENSION);
		headerWorkingplan.setWidthPercentage(100);

		// Même dénomination pour les cellules afin de mieux se repérer.
		PdfPCell cellLogo = new PdfPCell();
		PdfPCell cellTitle = new PdfPCell();
		PdfPCell cellDate = new PdfPCell();
		PdfPCell cellPage = new PdfPCell();
		cellLogo.setBorder(Rectangle.NO_BORDER);
		cellTitle.setBorder(Rectangle.NO_BORDER);
		cellDate.setBorder(Rectangle.NO_BORDER);
		cellPage.setBorder(Rectangle.NO_BORDER);

		String strNbWagons = LabelUtils.getLabel("print.doc.compo.nbwagons")
				+ " : " + sillon.getNbWagons();
		cellLogo.addElement(new Phrase(strNbWagons, FONT_TITRE_10));
		headerWorkingplan.addCell(cellLogo);

		String strOrigin = LabelUtils.getLabel("print.doc.form.destination")
				+ " : " + sillon.getDestination();
		cellTitle.addElement(new Phrase(strOrigin, FONT_TITRE_10));
		headerWorkingplan.addCell(cellTitle);

		String strTime = LabelUtils.getLabel("print.doc.form.departure.time")
				+ " : ";
		strTime += (sillon.getRealMovementTime() != null && sillon
				.getRealMovementTime().length() == 5) ? sillon
				.getRealMovementTime() : LabelUtils.getLabel("common.nc");

		cellDate.addElement(new Phrase(strTime, FONT_TITRE_10));
		headerWorkingplan.addCell(cellDate);

		cellPage.addElement(new Phrase("", FONT_TITRE_10));
		headerWorkingplan.addCell(cellPage);
		document.add(headerWorkingplan);
	}

	private void addCompositionCompositionPlan(PdfPTable table,
			Composition composition, Sillon sillon) throws DocumentException {

		PdfPCell cell;

		String length = (composition.getWagon().getType().getTotalLength() != 0) ? simpleDecimalFormat
				.format(composition.getWagon().getType().getTotalLength())
				: LabelUtils.getLabel("common.nc");

		String curb_weight = (composition.getWagon().getType().getCurbWeight() != 0) ? simpleDecimalFormat
				.format(composition.getWagon().getType().getCurbWeight())
				: LabelUtils.getLabel("common.nc");

		String lading_weight = ZERO;

		if (HubLading.LOADED.getValue().equals(
				composition.getWagon().getLading())) {
			lading_weight = (composition.getWagon().getWeightLading() > 0) ? simpleDecimalFormat
					.format(composition.getWagon().getWeightLading()) : "* "
					+ ZERO;
		}

		String total_weight = simpleDecimalFormat.format(composition.getWagon()
				.getType().getCurbWeight()
				+ composition.getWagon().getWeightLading());

		if ((composition.getWagon().getType().getCurbWeight() == 0 || composition
				.getWagon().getWeightLading() == 0)
				&& HubLading.LOADED.getValue().equals(
						composition.getWagon().getLading())) {
			total_weight = "* " + total_weight;
		}

		String brake_force = (composition.getWagon().getBrakeForce() > 0) ? Integer
				.toString((int) composition.getWagon().getBrakeForce()) : "* ";

		String destination = composition.getWagon().getDestinationLabel();

		cell = new PdfPCell(new Phrase(Integer.toString(composition.getWagon()
				.getCurrentPos().getPosNum() + 1), FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(WagonUtils.formatExtId(composition
				.getWagon().getExtId()), FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		table.addCell(cell);

		table.addCell(new Phrase(composition.getWagon().getLading(),
				FONT_TABLE_CELL));

		cell = new PdfPCell(new Phrase(length, FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(curb_weight, FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(lading_weight, FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(total_weight, FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(brake_force, FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		// Si train vide alors destination du sillon.
		if (HubLading.EMPTY.getValue().equalsIgnoreCase((sillon.getLading())))
			destination = sillon.getDestination();

		table.addCell(new Phrase(destination, FONT_TABLE_CELL));

		table.addCell(new Phrase(composition.getComment(), FONT_TABLE_CELL));
	}

	public void addCompositionPlanFooter(PdfPTable table, Sillon sillon,
			List<Composition> lstCompositions) throws DocumentException {

		List<String> lstTotal = calcTotal(sillon, lstCompositions);

		PdfPCell cell = new PdfPCell(new Phrase(
				LabelUtils.getLabel("print.doc.common.total") + " : ",
				FONT_TABLE_HEADER));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		cell.setColspan(3);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(lstTotal.get(0), FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(lstTotal.get(1), FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(lstTotal.get(2), FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(lstTotal.get(3), FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(lstTotal.get(4), FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase());
		cell.setBackgroundColor(Color.LIGHT_GRAY);
		cell.setColspan(2);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase("* "
				+ LabelUtils.getLabel("print.doc.common.legend"),
				FONT_TABLE_CELL));
		cell.setHorizontalAlignment(Element.ALIGN_LEFT);
		cell.setBorder(Rectangle.NO_BORDER);
		cell.setColspan(10);
		table.addCell(cell);
	}

	private List<String> calcTotal(Sillon sillon,
			List<Composition> lstCompositions) {

		// Les variables pour les totaux.
		float totalLength = 0;
		float totalCurbWeight = 0;
		float totalLadingWeight = 0;
		float totalBrakeForce = 0;

		boolean bTotalLength = true;
		boolean bTotalCurbWeight = true;
		boolean bTotalLadingWeight = true;
		boolean bTotalBrakeForce = true;

		for (Composition composition : lstCompositions) {
			Wagon wagon = composition.getWagon();

			// Longueur.
			totalLength += wagon.getType().getTotalLength();
			if (wagon.getType().getTotalLength() == 0)
				bTotalLength = false;

			// Tarre.
			totalCurbWeight += wagon.getType().getCurbWeight();
			if (wagon.getType().getCurbWeight() == 0)
				bTotalCurbWeight = false;

			// Masse freinée.
			totalBrakeForce += wagon.getBrakeForce();
			if (wagon.getBrakeForce() == 0)
				bTotalBrakeForce = false;

			// Poids de chargement.
			totalLadingWeight += wagon.getWeightLading();
			if (wagon.getWeightLading() == 0
					&& HubLading.LOADED.getValue().equals(wagon.getLading()))
				bTotalLadingWeight = false;

		}

		String strTotalLength = (bTotalLength) ? simpleDecimalFormat
				.format(totalLength) : LabelUtils.getLabel("common.nc");

		String strTotalCurbWeight = (bTotalCurbWeight) ? simpleDecimalFormat
				.format(totalCurbWeight) : LabelUtils.getLabel("common.nc");

		String strTotalBrakeForce = Integer.toString(((int) totalBrakeForce));
		if (!bTotalBrakeForce)
			strTotalBrakeForce = "* ";

		String strTotalLadingWeight = simpleDecimalFormat
				.format(totalLadingWeight);
		if (!bTotalLadingWeight)
			strTotalLadingWeight = "* " + strTotalLadingWeight;

		String strTotalWeight = simpleDecimalFormat.format(totalCurbWeight
				+ totalLadingWeight);

		if (!bTotalCurbWeight || !bTotalLadingWeight)
			strTotalWeight = "* " + strTotalWeight;

		// Si sillon vide alors on écrase certaines données
		if (HubLading.EMPTY.getValue().equals(sillon.getLading())) {
			strTotalWeight = strTotalCurbWeight;
			strTotalLadingWeight = ZERO;
		}

		List<String> lstTotal = new ArrayList<String>();
		lstTotal.add(strTotalLength);
		lstTotal.add(strTotalCurbWeight);
		lstTotal.add(strTotalLadingWeight);
		lstTotal.add(strTotalWeight);
		lstTotal.add(strTotalBrakeForce);

		return lstTotal;
	}
}